import React, { useState, useRef, useEffect } from 'react';
import { Upload, Button, Card, Row, Col, Spin, message, Select, Radio, Input } from 'antd';
import { InboxOutlined, CopyOutlined, DownloadOutlined, ArrowLeftOutlined } from '@ant-design/icons';
import Link from 'next/link';
import Layout from '../../components/layout/Layout';
import styles from '../../styles/ToolDetail.module.css';

const { Dragger } = Upload;
const { Option } = Select;
const { TextArea } = Input;

const OcrPage = () => {
  const [uploading, setUploading] = useState(false);
  const [processing, setProcessing] = useState(false);
  const [originalImage, setOriginalImage] = useState(null);
  const [recognizedText, setRecognizedText] = useState('');
  const [language, setLanguage] = useState('chi_sim');
  const [recognitionMode, setRecognitionMode] = useState('simple');
  const [imageFile, setImageFile] = useState(null);
  const [processingStatus, setProcessingStatus] = useState('');

  // 使用ref来存储识别结果，避免状态更新问题
  const resultTextRef = useRef('');
  
  // 当ref中的文本更新时，更新state
  useEffect(() => {
    if (resultTextRef.current && resultTextRef.current !== recognizedText) {
      console.log('从ref更新识别文本，长度:', resultTextRef.current.length);
      setRecognizedText(resultTextRef.current);
    }
  }, [resultTextRef.current, recognizedText]);

  // 支持的语言选项
  const languageOptions = [
    { value: 'chi_sim', label: '中文（简体）' },
    { value: 'eng', label: '英语' },
    { value: 'chi_tra', label: '中文（繁体）' },
    { value: 'jpn', label: '日语' },
    { value: 'kor', label: '韩语' },
    { value: 'fra', label: '法语' },
    { value: 'deu', label: '德语' },
    { value: 'rus', label: '俄语' },
  ];

  // 识别模式选项
  const modeOptions = [
    { value: 'fast', label: '快速模式' },
    { value: 'accurate', label: '精确模式' },
    { value: 'simple', label: '简单模式 (无需语言包)' },
    { value: 'debug', label: '调试模式' }
  ];

  // 上传前检查文件
  const beforeUpload = (file) => {
    const isImage = file.type.startsWith('image/');
    if (!isImage) {
      message.error('只能上传图片文件!');
      return false;
    }
    
    const isLt5M = file.size / 1024 / 1024 < 5;
    if (!isLt5M) {
      message.error('图片必须小于5MB!');
      return false;
    }
    
    // 显示原始图片预览
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => {
      setOriginalImage(reader.result);
      setImageFile(file);
      
      // 首次上传图片时显示提示
      if (!localStorage.getItem('ocrTipShown')) {
        message.info({
          content: '首次使用OCR功能时，已默认选择"简单模式"以确保功能正常。如需真实识别，可在上传后切换到其他模式。',
          duration: 8,
        });
        localStorage.setItem('ocrTipShown', 'true');
      }
    };
    
    return false; // 阻止自动上传
  };

  // 处理OCR识别
  const handleRecognize = async () => {
    if (!originalImage) {
      message.error('请先上传图片');
      return;
    }
    
    setProcessing(true);
    setRecognizedText('');
    setProcessingStatus('准备图片数据...');
    
    // 设置超时提示
    const loadingMessageKey = 'ocrLoadingMessage';
    message.loading({ content: '正在进行文字识别...', key: loadingMessageKey, duration: 0 });
    
    // 超时提示
    const timeoutWarning = setTimeout(() => {
      setProcessingStatus('仍在处理中，第一次识别可能需要下载语言数据...');
      message.info({
        content: '识别可能需要较长时间，请耐心等待。首次识别中文需要下载模型数据，可能需要1-2分钟。',
        key: 'timeoutWarning',
        duration: 8
      });
    }, 10000); // 10秒后显示提示
    
    // 如果30秒后仍在处理
    const longTimeoutWarning = setTimeout(() => {
      setProcessingStatus('处理时间较长，请考虑使用英语或切换到调试模式...');
      message.warning({
        content: '处理时间过长，可能是语言模型下载问题。建议取消并尝试使用英语或调试模式。',
        key: 'longTimeoutWarning',
        duration: 10
      });
    }, 30000);
    
    try {
      // 创建FormData对象
      const formData = new FormData();
      formData.append('image', imageFile);
      formData.append('language', language);
      formData.append('mode', recognitionMode);
      
      console.log('开始发送OCR请求', {
        language, 
        mode: recognitionMode,
        fileType: imageFile.type,
        fileSize: imageFile.size
      });
      
      setProcessingStatus('发送请求到服务器...');
      
      // 设置fetch超时
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), 120000); // 2分钟超时
      
      // 发送到后端API
      const response = await fetch('/api/image/ocr', {
        method: 'POST',
        body: formData,
        signal: controller.signal
      });
      
      clearTimeout(timeoutId);
      setProcessingStatus('服务器响应，处理结果中...');
      
      const result = await response.json();
      console.log('OCR响应结果:', result);
      
      if (response.ok && result.success) {
        console.log('OCR识别成功，结果长度:', result.text ? result.text.length : 0);
        
        if (result.text) {
          console.log('设置识别文本结果...');
          // 先保存到ref
          resultTextRef.current = result.text;
          console.log('已保存到ref，长度:', resultTextRef.current.length);
          
          // 强制更新UI
          setProcessingStatus('识别完成，更新结果...');
          
          // 延迟设置文本，确保UI状态已更新
          setTimeout(() => {
            // 使用ref中的值来设置state
            setRecognizedText(resultTextRef.current);
            console.log('识别文本已设置，长度:', resultTextRef.current.length);
            
            // 确保UI更新
            setTimeout(() => {
              console.log('结束处理状态...');
              setProcessingStatus('');
              setProcessing(false);
              
              message.success({ content: '文字识别成功！', key: loadingMessageKey });
            }, 200);
          }, 100);
        } else {
          console.log('服务器返回成功，但没有识别到文本');
          setProcessingStatus('');
          message.warning({ 
            content: '未识别到任何文字，请尝试调整设置或更换图片。', 
            key: loadingMessageKey 
          });
        }
      } else {
        console.error('OCR服务器返回错误:', result);
        setProcessingStatus('');
        throw new Error(result.message || '文字识别失败');
      }
    } catch (error) {
      console.error('OCR处理错误:', error);
      setProcessingStatus('');
      
      // 显示更有帮助的错误信息
      let errorMsg = error.message || '未知错误';
      
      if (error.name === 'AbortError') {
        errorMsg = '请求超时，请尝试使用快速模式或上传更小的图片';
      } else if (errorMsg.includes('undefined')) {
        errorMsg = '无法连接到OCR服务或服务返回无效结果。请尝试选择不同的语言或使用调试模式测试。';
      } else if (errorMsg.includes('language')) {
        errorMsg = '无法加载所选语言包，请尝试使用英语(eng)或简体中文(chi_sim)';
      } else if (errorMsg.includes('timeout') || errorMsg.includes('超时')) {
        errorMsg = 'OCR处理超时，请尝试使用快速模式或上传更小的图片';
      }
      
      message.error({ content: '文字识别失败: ' + errorMsg, key: loadingMessageKey });
    } finally {
      console.log('OCR处理完成，清理状态...');
      // 确保处理状态被重置
      setTimeout(() => {
        if (processing) {
          console.log('确保处理状态被重置');
          setProcessing(false);
        }
      }, 500);
      clearTimeout(timeoutWarning);
      clearTimeout(longTimeoutWarning);
    }
  };

  // 复制识别文本
  const copyToClipboard = () => {
    if (!recognizedText) return;
    
    navigator.clipboard.writeText(recognizedText)
      .then(() => {
        message.success('文本已复制到剪贴板');
      })
      .catch(err => {
        console.error('复制失败:', err);
        message.error('复制失败，请手动选择文本复制');
      });
  };

  // 下载识别文本
  const downloadText = () => {
    if (!recognizedText) return;
    
    const element = document.createElement('a');
    const file = new Blob([recognizedText], {type: 'text/plain'});
    element.href = URL.createObjectURL(file);
    element.download = 'ocr_result.txt';
    document.body.appendChild(element);
    element.click();
    document.body.removeChild(element);
  };

  return (
    <Layout title="OCR文字识别 - 在线工具平台" description="从图片中提取文字，支持多种语言">
      <div className={styles.toolHeader}>
        <div className={styles.container}>
          <Link href="/image-tools" className={styles.backLink} legacyBehavior>
            <a className={styles.backLink}>
              <ArrowLeftOutlined /> 返回图片工具
            </a>
          </Link>
          <h1 className={styles.toolTitle}>OCR文字识别</h1>
          <p className={styles.toolDescription}>
            从图片中识别并提取文字内容，支持多种语言和格式
          </p>
        </div>
      </div>

      <div className={styles.toolContent}>
        <div className={styles.container}>
          <Card className={styles.toolCard}>
            <div className={styles.uploadSection}>
              {!originalImage ? (
                <Dragger
                  name="file"
                  multiple={false}
                  beforeUpload={beforeUpload}
                  showUploadList={false}
                  disabled={uploading}
                >
                  <p className="ant-upload-drag-icon">
                    <InboxOutlined />
                  </p>
                  <p className="ant-upload-text">点击或拖拽图片到此区域上传</p>
                  <p className="ant-upload-hint">
                    支持PNG、JPG、JPEG等格式图片，图片中的文字越清晰，识别越准确
                  </p>
                  <div style={{marginTop: '15px', padding: '10px', border: '1px dashed #d9d9d9', maxWidth: '80%', margin: '0 auto'}}>
                    <p style={{fontWeight: 'bold', color: '#ff4d4f'}}>使用说明:</p>
                    <p>1. <b>简单模式</b>: 无需语言包，快速返回结果但不进行实际识别</p>
                    <p>2. <b>调试模式</b>: 仅测试系统连接，不处理图片</p>
                    <p>3. <b>快速模式</b>: 实际OCR识别，速度较快但准确度较低</p>
                    <p>4. <b>精确模式</b>: 实际OCR识别，准确度较高但速度较慢</p>
                    <p style={{color: '#ff4d4f'}}>首次使用时，建议先尝试简单模式或调试模式</p>
                  </div>
                </Dragger>
              ) : (
                <Row gutter={24}>
                  <Col xs={24} md={12}>
                    <div className={styles.ocrSettings}>
                      <h3>OCR设置</h3>
                      
                      <div className={styles.settingItem}>
                        <label>识别语言：</label>
                        <Select
                          value={language}
                          onChange={setLanguage}
                          style={{ width: '100%' }}
                        >
                          {languageOptions.map(option => (
                            <Option key={option.value} value={option.value}>
                              {option.label}
                            </Option>
                          ))}
                        </Select>
                      </div>
                      
                      <div className={styles.settingItem}>
                        <label>识别模式：</label>
                        <Radio.Group 
                          value={recognitionMode} 
                          onChange={e => setRecognitionMode(e.target.value)}
                        >
                          {modeOptions.map(option => (
                            <Radio key={option.value} value={option.value}>
                              {option.label}
                            </Radio>
                          ))}
                        </Radio.Group>
                        <p className={styles.settingHint}>
                          {recognitionMode === 'debug' 
                            ? '调试模式不进行实际识别，仅用于测试系统连接是否正常工作' 
                            : recognitionMode === 'simple'
                              ? '简单模式无需语言包，返回模拟结果（适合测试UI显示）'
                              : recognitionMode === 'fast'
                                ? '快速模式识别速度更快，但准确度可能较低'
                                : '精确模式识别更准确但耗时较长，可能需要下载语言包'}
                        </p>
                      </div>
                      
                      <div className={styles.imagePreview}>
                        <img src={originalImage} alt="预览" />
                      </div>
                      
                      <Button
                        type="primary"
                        size="large"
                        onClick={handleRecognize}
                        loading={processing}
                        block
                      >
                        开始识别
                      </Button>
                      
                      <Button
                        onClick={() => {
                          setOriginalImage(null);
                          setRecognizedText('');
                          setImageFile(null);
                        }}
                        style={{ marginTop: '10px' }}
                        block
                      >
                        重新上传
                      </Button>
                    </div>
                  </Col>
                  
                  <Col xs={24} md={12}>
                    <div className={styles.resultSection}>
                      <h3>识别结果</h3>
                      <Spin spinning={processing} tip={processingStatus || "正在进行文字识别，请稍候..."}>
                        <div className={styles.textResult}>
                          {recognizedText ? (
                            <>
                              <div style={{ width: '100%', marginBottom: '15px', border: '1px solid #d9d9d9', borderRadius: '2px', padding: '8px' }}>
                                <pre style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word', maxHeight: '300px', overflowY: 'auto', margin: 0 }}>
                                  {recognizedText}
                                </pre>
                              </div>
                              <div className={styles.actionButtons} style={{ marginTop: '10px' }}>
                                <Button
                                  type="primary"
                                  icon={<CopyOutlined />}
                                  onClick={copyToClipboard}
                                >
                                  复制文本
                                </Button>
                                <Button
                                  icon={<DownloadOutlined />}
                                  onClick={downloadText}
                                  style={{ marginLeft: '10px' }}
                                >
                                  下载文本
                                </Button>
                              </div>
                            </>
                          ) : (
                            <div className={styles.noResultText}>
                              {processing 
                                ? processingStatus || '正在识别中...' 
                                : '识别结果将显示在这里'}
                              
                              {processing && (
                                <Button 
                                  danger
                                  style={{ marginTop: '20px' }}
                                  onClick={() => {
                                    setProcessing(false);
                                    setProcessingStatus('');
                                    message.info('已取消识别操作');
                                  }}
                                >
                                  取消识别
                                </Button>
                              )}
                            </div>
                          )}
                        </div>
                      </Spin>
                      
                      {/* 调试信息 */}
                      {process.env.NODE_ENV === 'development' && (
                        <div style={{ marginTop: '20px', padding: '10px', border: '1px dashed #ccc' }}>
                          <p><strong>调试信息:</strong></p>
                          <p>状态: {processing ? '处理中' : '空闲'}</p>
                          <p>处理状态: {processingStatus || '无'}</p>
                          <p>识别文本长度: {recognizedText ? recognizedText.length : 0}</p>
                          <p>语言: {language}</p>
                          <p>模式: {recognitionMode}</p>
                          <Button 
                            type="dashed" 
                            size="small"
                            onClick={() => {
                              console.log('当前识别文本:', recognizedText);
                              if (!recognizedText) {
                                setRecognizedText('这是一段测试文本，用于验证显示功能是否正常工作。');
                              }
                            }}
                          >
                            测试显示
                          </Button>
                        </div>
                      )}
                    </div>
                  </Col>
                </Row>
              )}
            </div>
          </Card>
          
          <div className={styles.toolTips}>
            <h3>使用提示</h3>
            <ul>
              <li>图片越清晰，文字识别的准确率越高</li>
              <li>请确保选择正确的识别语言，以提高识别准确率</li>
              <li>对于复杂的排版，精确模式通常有更好的效果</li>
              <li>文字较多时，识别可能需要较长时间，请耐心等待</li>
              <li>如果识别结果不理想，可以尝试调整图片亮度/对比度后重新上传</li>
            </ul>
          </div>
        </div>
      </div>
    </Layout>
  );
};

export default OcrPage; 